/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package MetricsRetriever.RetrieverComponents;

import DataStructures.ProjectInformation;
import DataStructures.RepositoryData;
import General.FileManager;
import General.Globals;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.io.*;
import org.tmatesoft.svn.core.wc.*;

/**
 *
 * @author Manuel
 */
public class SVNManager implements RepositoryManager{

    private ProjectInformation info;
    private SVNClientManager manager;
    private FileManager fManager;
    private RepositoryData repoData;

    public SVNManager(ProjectInformation i,FileManager fm){
        info = i;
        manager = SVNClientManager.newInstance();
        fManager = fm;
        repoData = new RepositoryData();
    }

    public RepositoryData getAllRepositoryData() {
        ArrayList<String> fileList = null;
        repoData = new RepositoryData();
        boolean checkedOut = false;
        boolean logged = false;
        String link = info.getRepositoryLink();
        if(link == null || link.isEmpty())
            return null;

        checkedOut = this.checkout(link, Globals.DATA_DIRECTORY+"/"+info.getName()+"/source");
        ArrayList log = this.getHistory(link, -1);
        if(log != null){
            repoData.setRepositoryHistory(log);
            logged = true;
        }

        if(checkedOut && logged){
            fileList= fManager.process(Globals.DATA_DIRECTORY+"/"+info.getName()+"/source");
            repoData.setLOCs(fileList);
            //repoData.setOtherMetric(this.getOtherMetric
        }
        
        this.assessMetrics(log);

        return repoData;
    }


    private void assessMetrics(ArrayList<String> files) {
        if(files != null){
            //repoData....
        }
        //TODO implement
    }





    //SVN SUPPORT
   

    public boolean checkout(String url, String destination){
        boolean success = false;
        int counter = 0;
        while(!success && counter<3){
            counter++;
            this.setupSVN();
            try {
                File destFile = new File(destination);
                if (!destFile.exists() || !destFile.isDirectory()) {
                    destFile.mkdirs();
                }
                SVNUpdateClient updateClient = manager.getUpdateClient();
                updateClient.doCheckout(SVNURL.parseURIEncoded(url), destFile, SVNRevision.UNDEFINED, SVNRevision.HEAD, SVNDepth.INFINITY, false);
                success = true;
                manager.getWCClient().doCleanup(destFile);
            } catch (SVNException ex) {
                ex.printStackTrace();
            }
        }
        return success;
    }

    public ArrayList getHistory(String url, int maxEntries){
        this.setupSVN();
        ArrayList<SVNLogEntry> logEntries = null;
        maxEntries--;
        try {
            SVNRevision.HEAD.getNumber();
            SVNRepository repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(url));
            long endRevision = SVNRevision.HEAD.getNumber();
            long startRevision = endRevision - maxEntries;
            if(maxEntries < 0 || startRevision < 0)
                startRevision = 0;
            Collection e = repository.log(new String[]{""}, null, startRevision, endRevision, true, true);
            logEntries = new ArrayList<SVNLogEntry>(e);
            for(int i = 0;i<logEntries.size();i++){
                SVNLogEntry currentEntry = logEntries.get(i);
            }

        } catch (Exception ex) {
                //System.err.println("Error logging "+url);
        }
        return logEntries;

    }

     public void setupSVN(){

         DAVRepositoryFactory.setup();
         //svn://, svn+xxx:// (svn+ssh:// in particular)
         SVNRepositoryFactoryImpl.setup();
         //file:///
         FSRepositoryFactory.setup();


    }





}

